/**
 *    Copyright (C) 2008, 2009  Victor Smirnov <aist11@gmail.com>
 *
 *    This program is free software; you can redistribute it and/or modify
 *    it under the terms of the GNU General Public License as published by
 *    the Free Software Foundation; either version 3 of the License, or
 *    (at your option) any later version.
 *
 *    This program is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU General Public License for more details.
 *
 *    You should have received a copy of the GNU General Public License along
 *    with this program; if not, write to the Free Software Foundation, Inc.,
 *    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 *    See LICENSE.exceptions in the root folder of this project for possible
 *    exceptions
 *
 */

#ifndef _CUBEFS_API_METADATA_METADATA_HPP
#define _CUBEFS_API_METADATA_METADATA_HPP

#include <cubefs/api/types.hpp>
#include <cubefs/api/reflection.hpp>

#include <cubefs/core/tools/types/traits.hpp>
#include <cubefs/core/tools/types/typelist.hpp>
#include <cubefs/core/tools/types/typemap.hpp>
#include <cubefs/core/tools/bitmap.hpp>

#include <vector>
#include <map>
#include <string>

namespace cubefs    {
namespace api       {

class Metadata;
class PageMetadata;
class ModelMetadata;
class FieldMetadata;
struct Container;
struct Model;

typedef std::vector<Metadata*>          MetadataList;
typedef std::map<Int, PageMetadata*>    PageMetadataMap;
typedef std::map<Int, ModelMetadata*>   ModelMetadataMap;
typedef std::map<Int, FieldMetadata*>   PtrMap;

typedef Model* (*ModelFactoryFn) (TypedIDValue* rootId, Container *container, BigInt name);
typedef Int (*PageSizeProviderFn)(const void *page);

struct CUBEFS_API Metadata: public Typed {
    enum   {BYTE,   UBYTE,  SHORT,   USHORT, INT,    UINT,
            BIGINT, ID,     BITMAP,  FLAG,   GROUP,  PAGE,
            MODEL,  CONTAINER};

    virtual StringRef Name() const  = 0;
    virtual Int GetTypeCode() const = 0;

    static Type* MyType();
};

CUBEFS_DECLARE_TYPENAME(Metadata,    "cubefs::api::metadata::Metadata");

struct CUBEFS_API Page: public Typed {

    virtual IDValue GetId()                     = 0;
    virtual Int GetModelHash()                  = 0;
    virtual Int GetPageTypeHash()               = 0;
    virtual BigInt GetFlags()                   = 0;
    virtual void* Ptr()                         = 0;
    virtual void SetPtr(void* ptr)              = 0;
    virtual bool IsNull() const					= 0;

    virtual Int Size()                          = 0;
    virtual Int GetByte(Int idx)                = 0;
    virtual void SetByte(Int idx, Int value)    = 0;

    static Type* MyType();
};

CUBEFS_DECLARE_TYPENAME(Page,    "cubefs::api::metadata::Page");


void InitMetadataTypes();
void DestroyMetadataTypes();

}}

#endif
